package com.music.service.songs.dao.impl;


import static com.music.service.songs.constants.SongSQLQueries.ADD_NEW_SONG;
import static com.music.service.songs.constants.SongSQLQueries.CHECK_SONG_PERMISSION;
import static com.music.service.songs.constants.SongSQLQueries.DELETE_SONG;
import static com.music.service.songs.constants.SongSQLQueries.EDIT_SONG_NAME;
import static com.music.service.songs.constants.SongSQLQueries.GET_SONGS_FROM_PLAYLIST_ID;
import static com.music.service.songs.constants.SongSQLQueries.SET_PREFERRED_URL_FOR_SONG_FOR_MEMBER;
import static com.music.service.songs.constants.SongSQLQueries.VIEW_SONGS;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;

import com.music.service.folders.mapper.CountMapper;
import com.music.service.songs.beans.Song;
import com.music.service.songs.constants.SongState;
import com.music.service.songs.dao.SongDAO;
import com.music.service.songs.mapper.SongMapper;

public class SongDAOImpl implements SongDAO {
	private JdbcTemplate mMusicsTemplate;

		
	/**
	 * @return the musicsTemplate
	 */
	public JdbcTemplate getMusicsTemplate() {
		return mMusicsTemplate;
	}

	/**
	 * @param pMusicsTemplate the musicsTemplate to set
	 */
	@Required
	public void setMusicsTemplate(JdbcTemplate pMusicsTemplate) {
		mMusicsTemplate = pMusicsTemplate;
	}

	@Override
	public boolean addNewSong(final Long pMemberId, final String pSongName) {
		int nRowsUpdated = getMusicsTemplate().update(ADD_NEW_SONG,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)
							throws SQLException {
						preparedStatement.setLong(1, pMemberId);
						preparedStatement.setString(2, pSongName);
						preparedStatement.setInt(3, SongState.ACTIVE.getState());
					}
				});
		return nRowsUpdated == 1;
	}
	
	@Override
	public boolean deleteSong(final Long pMemberId,final Long pSongId) {
		int nRowsUpdated = getMusicsTemplate().update(DELETE_SONG,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)
							throws SQLException {
						preparedStatement.setInt(1, SongState.DELETED.getState());
						preparedStatement.setLong(2, pSongId);
						preparedStatement.setLong(3, pMemberId);
						preparedStatement.setInt(4, SongState.VERIFIED.getState());
					}
				});
		return nRowsUpdated == 1;
	}

	@Override
	public boolean editSongName(final Long pMemberId, final Long pSongId,final String pSongName) {
		int nRowsUpdated = getMusicsTemplate().update(EDIT_SONG_NAME,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)
							throws SQLException {
						preparedStatement.setString(1, pSongName);
						preparedStatement.setLong(2, pSongId);
						preparedStatement.setLong(2, pMemberId);
						preparedStatement.setInt(3, SongState.ACTIVE.getState());
					}
				});
		return nRowsUpdated == 1;
	}
	
	@Override
	public boolean setPreferredUrlForSongForMember(final Long pMemberId, final Long pSongId,final Long pUrlId) {
		int nRowsUpdated = getMusicsTemplate().update(SET_PREFERRED_URL_FOR_SONG_FOR_MEMBER,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)
							throws SQLException {
						preparedStatement.setLong(1, pUrlId);
						preparedStatement.setLong(2, pSongId);
						preparedStatement.setLong(2, pMemberId);
					}
				});
		return nRowsUpdated == 1;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<Song> viewSongs(final Long... pSongIds){
		List<Song> songs = new ArrayList<Song>();
		
		//Check alteast one song id is specified.
		if(pSongIds != null && pSongIds.length > 0){
		
			StringBuilder sb = new StringBuilder("");
			for(Long songId : pSongIds){
				sb.append(","+String.valueOf(songId));
			}
			String songIds = sb.substring(1);
			String sql = VIEW_SONGS.replaceFirst("?",songIds);
			songs = getMusicsTemplate().query(sql,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)	throws SQLException {
						preparedStatement.setInt(1, SongState.DELETED.getState());
					}
				}, new SongMapper());
		}
		return songs;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Song> getSongsFromPlaylistId(final Long pPlaylistId) {
		List<Song> songs = new ArrayList<Song>();
		
		songs = getMusicsTemplate().query(GET_SONGS_FROM_PLAYLIST_ID,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)	throws SQLException {
						preparedStatement.setLong(1, pPlaylistId);
						preparedStatement.setInt(2, SongState.DELETED.getState());
					}
				}, new SongMapper());
	
		return songs;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public boolean checkMemberPermissionForSong(final Long pMemberId,final Long pSongId) {
		List<Integer> counts = getMusicsTemplate().query(
				CHECK_SONG_PERMISSION, new PreparedStatementSetter() {
					public void setValues(PreparedStatement preparedStatement)throws SQLException {
						preparedStatement.setLong(1, pSongId);
						preparedStatement.setLong(2, pMemberId);
						preparedStatement.setInt(3, SongState.ACTIVE.getState());
					}
				}, new CountMapper());

		if (!counts.isEmpty()) {
			return counts.get(0) == 1;
		}
		return false;
	}

	
	
}
